/**
 * Writed by yura and mak
 */

package wz.legend.handlers.fighting;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import wz.legend.Context;
import wz.legend.HttpContext;
import wz.legend.StateContext;
import wz.legend.Status;
import wz.legend.db.DBManager;
import wz.legend.handlers.ResponseHandler;
import wz.legend.handlers.auction.Lot;
import wz.legend.handlers.auction.Product;
import wz.legend.handlers.steps.Step;
import wz.legend.handlers.steps.StepLoader;
import wz.legend.handlers.steps.StepMachine;
import wz.legend.handlers.steps.StepMachineImpl;
import wz.legend.util.ItemUtils;
import wz.legend.util.StepNullTimerTask;
import wz.legend.util.UriConstants;
import wz.legend.util.Utils;


public class FightingHandler implements ResponseHandler {
    static final String CONTEXT_KEY = "Fighting";

    private static final Logger LOG = Logger.getLogger(FightingHandler.class);

    private StepMachine stepMachine = null;
    private String stepsFileName = null;
    private long stepsTimeout = 6000;
    private long nullRequestTime = 1000;

    private Timer timer;
    private TimerTask timerTask;

    public FightingHandler() {
    }

    private void init() {
        InputStream stream = null;
        List<Step> steps = new ArrayList<Step>();
        if (null != stepsFileName && !"".equals(stepsFileName)) {
            stream = FightingHandler.class.getClassLoader()
                    .getResourceAsStream(stepsFileName);
            steps = StepLoader.loadSteps(stream);
        }
        stepMachine = new StepMachineImpl(steps);
        stepMachine.setTimeoutStepStart(stepsTimeout);
    }

    public void handle(HttpContext httpContext, Context context) {
        try {
            if (context.getStatus() == Status.FIGHTING) {
                if (timer == null) {
                    timer = new Timer();
                    timerTask = new StepNullTimerTask(this, context, Status.FIGHTING);
                    timer.schedule(timerTask, nullRequestTime, nullRequestTime);
                    LOG.debug("nullTimer started");
                }

                if (stepMachine == null) {
                    init();
                }

                String uri = "";
                if (httpContext != null) {
                    uri = httpContext.getRequest().getRequestLine().getUri();
                }

                if (!stepMachine.isDone()) {
                    stepMachine.handle(httpContext, context);
                } else {
                    stepMachine.reset();
                    LOG.debug("start new cycle");
                }
            } else {
                if (stepMachine != null) {
                    stepMachine.reset();
                }

                if (timer != null) {
                    timerTask.cancel();
                    timer.cancel();
                    timer = null;
                    timerTask = null;
                    LOG.debug("nullTimer stoped");
                }
            }
        } catch (Exception e) {
            LOG.error(e, e);
            throw new RuntimeException(e);
        }
    }

    // List<Node> parseFightInfo(Document document) throws Exception {
    // Node nodeTable = (Node) path.evaluate(TABLE, document,
    // XPathConstants.NODE);
    //
    // NodeList userNodeList = (NodeList) path.evaluate(USERS, nodeTable,
    // XPathConstants.NODESET);
    //
    // List<Node> list = Utils.convertNodeList(userNodeList);
    // for (Node node : list) {
    // System.out.println(node.getTextContent());
    // }
    // return list;
    // }

    public long getStepsTimeout() {
        return stepsTimeout;
    }

    public void setStepsTimeout(long stepsTimeout) {
        this.stepsTimeout = stepsTimeout;
    }

    public long getNullRequestTime() {
        return nullRequestTime;
    }

    public void setNullRequestTime(long nullRequestTime) {
        this.nullRequestTime = nullRequestTime;
    }

    public StepMachine getStepMachine() {
        return stepMachine;
    }

    public void setStepMachine(StepMachine stepMachine) {
        this.stepMachine = stepMachine;
    }
    
    public String getStepsFileName() {
        return stepsFileName;
    }

    public void setStepsFileName(String stepsFileName) {
        this.stepsFileName = stepsFileName;
    }
}
